package com.lancoo.ccas52.controller;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.lancoo.ccas52.aspect.RateLimiter;
import com.lancoo.ccas52.entity.CssTaskInfo;
import com.lancoo.ccas52.entity.RuleWeekDay;
import com.lancoo.ccas52.entity.Student;
import com.lancoo.ccas52.entity.TaskInfo;
import com.lancoo.ccas52.mapper.TaskInfoMapper;
import com.lancoo.ccas52.pojo.common.PageInfo;
import com.lancoo.ccas52.pojo.response.basicPlatform.UserInfo;
import com.lancoo.ccas52.pojo.vo.*;
import com.lancoo.ccas52.service.*;
import com.lancoo.ccas52.service.mobileService.MobileStudentService;
import com.lancoo.ccas52.util.PagingUtil;
import com.lancoo.ccas52.util.ResponseObject;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @ClassName MobileSelectCourseController
 * @Description 移动端选课
 * @Author pengrui
 * @Date 2023/6/25
 */
@Api(tags = "移动端选课")
@RestController
@RequestMapping("/api/v5.2.1/mobile/selectCourse")
public class MobileSelectCourseController {


    @Autowired
    private TaskInfoService taskInfoService;

    @Autowired
    private MobileStudentService mobileStudentService;

    @Autowired
    private CourseService courseService;

    @Autowired
    private StudentService studentService;

    @Autowired
    private TimetableService timetableServiceImpl;

    @Autowired
    private CssTaskInfoService cssTaskInfoService;

    @Autowired
    private YunBasicService yunBasicService;

    @Autowired
    private BasicRuleService basicRuleService;

    @Resource
    private TaskInfoMapper taskInfo ;


    @ApiOperation("根据token获取用户信息")
    @GetMapping("/getUserDetailInfoByToken")
    public ResponseObject<UserInfo> getUserDetailInfoByToken(@ApiParam(value = "token", required = true) @RequestHeader("Authorization") String token,
                                                             @ApiParam(value = "任务id", required = false) @RequestHeader(required = false) Integer taskId) {
        UserInfo userInfoByToken = yunBasicService.getUserInfoByToken(token, taskId);
        return ResponseObject.ofSuccess(userInfoByToken);
    }

    @ApiOperation("根据基础平台学生Id获取学生信息")
    @GetMapping(value = "/getStudentInfoByBaseStudentId")
    public ResponseObject<Student> getStudentInfoByBaseStudentId(@ApiParam(value = "任务流程id", required = true) @RequestHeader Integer taskId,
                                                                 @ApiParam(value = "基础平台学生id ", required = true) @RequestParam String baseStudentId) {
        return ResponseObject.ofSuccess(studentService.getStudentByBaseStudentId(taskId, baseStudentId));
    }

//    @ApiOperation("获取选课计划")
//    @GetMapping(value = "/getCssTask")
//    public ResponseObject<List<CssTaskInfo>> getCssTask(@ApiParam(value = "学校id", required = true) @RequestParam String schoolId,
//                                                        @ApiParam(value = "1预选 2正式选课", required = false) @RequestParam(required = false) Integer type,
//                                                        @ApiParam(value = "名称模糊查询", required = false) @RequestParam(required = false) String keyWord,
//                                                        @ApiParam(value = "基础平台学生id", required = false) @RequestParam(required = false) String baseStudentId) {
//        return ResponseObject.ofSuccess(cssTaskInfoService.getCssTaskBySchool(schoolId, type, keyWord, baseStudentId));
//    }


    @GetMapping("/getWeekDays")
    @ApiOperation("获取课时方案设置")
    public ResponseObject<List<RuleWeekDay>> getWeekDays(@ApiParam(value = "任务流程id", required = true) @RequestHeader Integer taskId,
                                                         @ApiParam(value = "学校Id", required = true) @RequestParam String schoolId) {
        return ResponseObject.ofSuccess(basicRuleService.getWeekDays(schoolId, taskInfo.selectOne(new LambdaQueryWrapper<TaskInfo>().eq(TaskInfo::getTaskId,taskId)).getTerm()));
    }

//    @GetMapping("/getMaxPeriodScheme")
//    @ApiOperation("获取最大课时方案")
//    public ResponseObject<MaxPeriodScheme> getMaxPeriodScheme(@ApiParam(value = "任务流程id", required = true) @RequestHeader Integer taskId,
//                                                              @ApiParam(value = "学校Id", required = true) @RequestParam String schoolId) {
//        return ResponseObject.ofSuccess(basicRuleService.getMaxPeriodScheme(schoolId, taskInfo.selectOne(new LambdaQueryWrapper<TaskInfo>().eq(TaskInfo::getTaskId,taskId)).getTerm()));


    @GetMapping("/getMaxPeriodScheme")
    @ApiOperation("获取最大课时方案")
    public ResponseObject<Integer> getMaxPeriodScheme(@ApiParam(value = "任务流程id", required = true) @RequestHeader Integer taskId,
                                                              @ApiParam(value = "学校Id", required = true) @RequestParam String schoolId) {
        return ResponseObject.ofSuccess(basicRuleService.getMaxPeriodScheme(schoolId, taskInfo.selectOne(new LambdaQueryWrapper<TaskInfo>().eq(TaskInfo::getTaskId,taskId)).getTerm()).getPeriodSchemes().size());
    }


    @ApiOperation("获取可选课程列表")
    @GetMapping(value = "/getSelectCourseList")
    public ResponseObject<PageInfo<StudentTeachingClass>> getSelectCourseList(@ApiParam(value = "任务流程id", required = true) @RequestHeader Integer taskId,
                                                                              @ApiParam(value = "学生id ", required = true) @RequestParam Long studentId,
                                                                              @ApiParam(value = "0无需选课 1在线选课;2:分级教学 3:预选教学班", required = true) @RequestParam Integer teachingClassType,
                                                                              @ApiParam(value = "课程类别id 传null全部", required = false) @RequestParam(required = false) String courseTypeId,
                                                                              @ApiParam(value = "课程性质 0全部 1必修  2选修", required = false) @RequestParam(required = false) Integer courseNature,
                                                                              @ApiParam(value = "学分 4：3分以上 ", required = false) @RequestParam(required = false) Double credit,
                                                                              @ApiParam(value = "修读性质：1主修2辅修", required = true) @RequestParam(required = true) Integer studyNature,
                                                                              @ApiParam(value = "课程名模糊查询", required = false) @RequestParam(required = false) String keyWord,
                                                                              @ApiParam(value = "1显示可选课程，默认0表示所有课程 ", required = false) @RequestParam(required = false,defaultValue = "0") Integer isAllCourse,
                                                                              @ApiParam(value = "轮次id 在线选课必传 ", required = false) @RequestParam(required = false) Integer roundId,
                                                                              @ApiParam(value = "页码", required = true) @RequestParam Integer currentPage,
                                                                              @ApiParam(value = "页容", required = true) @RequestParam Integer pageSize) {
        return ResponseObject.ofSuccess(studentService.getAvailableTeachingClass(taskId, currentPage, pageSize, studentId, teachingClassType, courseTypeId, courseNature, credit, studyNature, keyWord, isAllCourse,roundId));

    }

    @ApiOperation("获取课程/环节类别")
    @GetMapping(value = "/getType")
    public ResponseObject<List<CourseTypeDto>> getTeacherPlan(@ApiParam(value = "任务流程id", required = true) @RequestHeader Integer taskId,
                                                              @ApiParam(value = "1课程 2环节", required = true) @RequestParam Integer flag) {
        return ResponseObject.ofSuccess(courseService.getCourseTypeByTaskId(taskId, flag));

    }

    @ApiOperation("获取学生已选课程")
    @GetMapping(value = "/getStudentSelectedCourseList")
    public ResponseObject<List<StudentTeachingClass> > getStudentSelectedCourseList(@ApiParam(value = "任务流程id", required = true) @RequestHeader Integer taskId,
                                                                                    @ApiParam(value = "学生id ", required = true) @RequestParam Long studentId,
                                                                                    @ApiParam(value = "0无需选课 1在线选课;2:分级教学 3:预选教学班", required = true) @RequestParam Integer teachingClassType,
                                                                                    @ApiParam(value = "修读性质：0全部1主修2辅修", required = true) @RequestParam(required = true) Integer studyNature)
    {
        return ResponseObject.ofSuccess(mobileStudentService.getSelectedByStudentId(taskId, studentId, teachingClassType,studyNature));
    }

    @ApiOperation("获取学生选课统计情况")
    @GetMapping(value = "/getStudentSelectedCourseStatistics")
    public ResponseObject<SelectedCourseStatistics> getStudentSelectedCourseStatistics(@ApiParam(value = "任务流程id", required = true) @RequestHeader Integer taskId,
                                                                                       @ApiParam(value = "学生id ", required = true) @RequestParam Long studentId,
                                                                                       @ApiParam(value = "0无需选课 1在线选课;2:分级教学 3:预选教学班", required = true) @RequestParam Integer teachingClassType)
    {
        return ResponseObject.ofSuccess(mobileStudentService.getStudentSelectedCourseStatisticsByStudentId(taskId, studentId, teachingClassType));
    }

    @ApiOperation("获取学生选课数量和总学分")
    @GetMapping(value = "/getCourseAndCredit")
    public ResponseObject<SelectedCourseStatistics> getCourseAndCredit(@ApiParam(value = "任务流程id", required = true) @RequestHeader Integer taskId,
                                                                       @ApiParam(value = "学生id ", required = true) @RequestParam Long studentId,
                                                                       @ApiParam(value = "0无需选课 1在线选课;2:分级教学 3:预选教学班", required = true) @RequestParam Integer teachingClassType)
    {
        return ResponseObject.ofSuccess(mobileStudentService.getCourseAndCreditStatistics(taskId, studentId, teachingClassType));
    }


    @ApiOperation("获取课程详情")
    @GetMapping(value = "/getCourseDetail")
    public ResponseObject<StudentTeachingClass> getCourseDetail(@ApiParam(value = "任务流程id", required = true) @RequestHeader Integer taskId,
                                                                @ApiParam(value = "学生id ", required = true) @RequestParam Long studentId,
                                                                @ApiParam(value = "0无需选课 1在线选课;2:分级教学 3:预选教学班", required = true) @RequestParam Integer teachingClassType,
                                                                @ApiParam(value = "教学班id", required = true) @RequestParam Long teachingClassId)
    {
        return ResponseObject.ofSuccess(mobileStudentService.getCourseDetail(taskId, studentId, teachingClassType, teachingClassId));
    }

    @ApiOperation("学生退课数量")
    @GetMapping(value = "/getCanceledCourseNum")
    public ResponseObject<Integer> getCanceledCourseNum(@ApiParam(value = "任务流程id", required = true) @RequestHeader Integer taskId,
                                                        @ApiParam(value = "0无需选课 1在线选课;2:分级教学 3:预选教学班", required = true) @RequestParam Integer teachingClassType,
                                                        @ApiParam(value = "学生id ", required = true) @RequestParam Long studentId) {
        return ResponseObject.ofSuccess(mobileStudentService.getCanceledCourseNum(taskId,teachingClassType ,studentId));
    }


    @ApiOperation("获取选课要求")
    @GetMapping(value = "/getSelectionRequire")
    public ResponseObject<SelectionRequireVo> getSelectionRequire(@ApiParam(value = "任务流程id", required = true) @RequestHeader Integer taskId,
                                                                  @ApiParam(value = "学生id ", required = true) @RequestParam Long studentId,
                                                                  @ApiParam(value = "修读性质：1主修2辅修", required = true) @RequestParam(required = true) Integer studyNature) {
        return ResponseObject.ofSuccess(studentService.getSelectionRequire(taskId, studentId, studyNature));
    }

    @ApiOperation("判断是否已选择该课程")
    @GetMapping(value = "/isExistSelectCourse")
    public ResponseObject<StudentTeachingClass> isExistSelectCourse(@ApiParam(value = "任务流程id", required = true) @RequestHeader Integer taskId,
                                                                    @ApiParam(value = "学生id ", required = true) @RequestParam Long studentId,
                                                                    @ApiParam(value = "教学班类型 1在线选课 3预选", required = true) @RequestParam Integer teachingClassType,
                                                                    @ApiParam(value = "1主修 2辅修", required = true) @RequestParam Integer studyNature,
                                                                    @ApiParam(value = "课程id", required = true) @RequestParam Long courseId) {
        return ResponseObject.ofSuccess(studentService.isExistSelectCourse(taskId, studentId, teachingClassType, studyNature, courseId));

    }


    @ApiOperation("判断学生是否是禁选学生")
    @GetMapping(value = "/isProhibitStudent")
    public ResponseObject<Boolean> isProhibitStudent(@ApiParam(value = "学生id ", required = true) @RequestParam Long studentId) {
        return ResponseObject.ofSuccess(studentService.isProhibitStudent(studentId));
    }

    @ApiOperation("学生选课")
    @PostMapping(value = "/studentSelectCourse")
    public ResponseObject<Object> selectCourse(@ApiParam(value = "任务流程id", required = true) @RequestHeader Integer taskId,
                                               @ApiParam(value = "学生id ", required = true) @RequestParam Long studentId,
                                               @ApiParam(value = "教学班id", required = true) @RequestParam Long teachingClassId,
                                               @ApiParam(value = "退选教学班id", required = false) @RequestParam(required = false) Long cancelTeachingClassId) {
        int res = studentService.selectCourse(taskId, studentId, teachingClassId, cancelTeachingClassId);
        switch (res) {
            case 1:
                return ResponseObject.ofSuccess("选课成功");
            case -1:
                return ResponseObject.ofFail(2, "选课已满，无法继续选课");
            case -2:
                return ResponseObject.ofFail(2, "Redis服务连接异常，请联系管理员");
            case -3:
                return ResponseObject.ofFail(5, "已添加相同课程下的教学班，请勿重复选择");
            case -4:
                return ResponseObject.ofFail(2, "不存在该教学班");
            default:
                return ResponseObject.ofFail(2, "选课失败，请重试");
        }
    }

    @ApiOperation("学生退课")
    @PostMapping(value = "/studentCancelCourse")
    public ResponseObject<String> studentCancelCourse(@ApiParam(value = "任务流程id", required = true) @RequestHeader Integer taskId,
                                                      @ApiParam(value = "学生id ", required = true) @RequestParam Long studentId,
                                                      @ApiParam(value = "教学班id", required = true) @RequestParam Long teachingClassId,
                                                      @ApiParam(value = "2退选   3管理员移除", required = true) @RequestParam Integer flag) {
        int res = studentService.cancelCourse(taskId, studentId, teachingClassId, flag);
        switch (res) {
            case 1:
                return ResponseObject.ofSuccess("退选成功");
            case -2:
                return ResponseObject.ofFail(2, "Redis服务连接异常，请联系管理员");
            case -4:
                return ResponseObject.ofFail(2, "不存在该教学班");
            default:
                return ResponseObject.ofFail(2, "退选失败，请重试");
        }
    }


    @ApiOperation("获取学生课表")
    @GetMapping(value = "/getStudentCourseTimetable")
    public ResponseObject< List< StudentTeachingClass> > getStudentCourseTimetable(@ApiParam(value = "任务流程id", required = true) @RequestHeader Integer taskId,
                                                                                  @ApiParam(value = "学生id ", required = true) @RequestParam Long studentId)
    {
        return ResponseObject.ofSuccess(studentService.getSelectedByStudentId(taskId,studentId,1));
    }
}
